(function(window){

var 
	mooluMake = function(obj){
		return new muMake(obj);
	},
	
	muMake = function(obj){
		var 
			grids = obj.grids;
		
		this.grids = grids;
	},
	
	aider = {
		
		counter : 0,
		
		runid : 0,
		
		/**
			string of binary to 
			string of 36 hex
		*/
		transcode : function(binaryCode, flag){
			
			if(flag){
			
				return parseInt(binaryCode, 36)
				   .toString(2).substr(1);
			
			}else{
			
    			return parseInt('1' + binaryCode, 2)
				   	.toString(36);
			
			}
		},
		/**
			different colors represent different numbers
			rgb(192, 192, 192)  ---  0
			rgb(192, 192, 192)  ---  1
		*/		
		state : function(elem){
			var
				color = this.getElStyle(elem, 'backgroundColor');
				
			if(color == 'rgb(192, 192, 192)' || 
						color == 'rgb(192,192,192)')
				return '0';
			else
				return '1';
			
		},
		/**
			when we click the grids change
			the color of it under conditions
		*/
		make : function(context){
			var 
				grids = context.grids,
				self = this;
			
			this.ref = context;
			
			for(var i=0; i<grids.length; i++){
				addEvent(grids[i], 'click', function(){
					var 
						color = self.
							getElStyle(this, 'backgroundColor');
					
					if(color == 'rgb(192, 192, 192)' || 
					   				color == 'rgb(192,192,192)')
						this.style.backgroundColor 
									= 'rgb(128, 128, 128)';
					
					else
						this.style.backgroundColor 
									= 'rgb(192, 192, 192)';
					
				});
			}
			
			return this;
		},
		/**
			get the current style of the elements
		*/
		getElStyle: function(el, p) { 
			var 
				curElSty = el.currentStyle || 
							window.getComputedStyle(el, null),
				elSty    = el.style;
			
			if(p === "opacity") {
				return elSty.opacity || 
					curElSty.opacity ||
					(el.filters.alpha ? 
					 el.filters.alpha.opacity : 100) / 100;
			}
			
			return elSty[p] || curElSty[p];
		},
		/**
			monitor click event
		*/
		monitorClick : function(){
			var 
				grids = this.ref.grids,
				self = this,
				
				print = document.getElementById('print'),
				all128 = document.getElementById('all128'),
				all192 = document.getElementById('all192'),
				up = document.getElementById('upmove'),
				down = document.getElementById('downmove'),
				left = document.getElementById('leftmove'), 
				right = document.getElementById('rightmove'),
				
				update = document.getElementById('histUpdate'),
				run = document.getElementById('run');
		
			addEvent(print, 'click', function(){
				
				var parts = self.gridsStyles();				
				self.span(parts.join('-'));
			});

			addEvent(all128, 'click', function(){
					
				for(var i=0; i<grids.length; i++){
				
				    grids[i].style.backgroundColor = 
						'rgb(128, 128, 128)';	
				}
				
			});

			addEvent(all192, 'click', function(){
					
				for(var i=0; i<grids.length; i++){
				
				    grids[i].style.backgroundColor = 
						'rgb(192, 192, 192)';	
				}
				
			});

			addEvent(up, 'click', function(){
			
				var 
					styles = self.gridsStyles(),
					newStyles = [],
					fill = [],
					
					count = self.counter,
					id = 'history' + count;
					
				for(var i=0; i<30; i++){
				    fill.push('1');
				}
								
				for(var i=0; i<19; i++){
				    newStyles.push(styles[i + 1]);
				}
				
				newStyles[19] = aider.transcode(fill.join(''));
				
				self.span(newStyles.join('-'));
				aider.setFrame(id, newStyles.join('-'));
				
			});	
			
			addEvent(down, 'click', function(){
			
				var 
					styles = self.gridsStyles(),
					newStyles = [],
					fill = [],
					
					count = self.counter,
					id = 'history' + count;
					
				for(var i=0; i<30; i++){
				    fill.push('1');
				}
				
				newStyles.push(aider.transcode(fill.join('')));
				
				for(var i=0; i<19; i++){
				    newStyles.push(styles[i]);
				}
				
				self.span(newStyles.join('-'));
				aider.setFrame(id, newStyles.join('-'));
				
			});

			addEvent(left, 'click', function(){
			
				var 
					styles = self.gridsStyles(),
					newStyles = [],
					fill = '1',
					temp, tmp,
					
					count = self.counter,
					id = 'history' + count;
								
				for(var i=0; i<20; i++){
					temp = self.transcode(styles[i], true).split('');
					temp.push(fill);
					temp.shift();
					tmp = self.transcode(temp.join(''));
					newStyles.push(tmp);
				}
				
				self.span(newStyles.join('-'));
				aider.setFrame(id, newStyles.join('-'));
				
			});
			
			addEvent(right, 'click', function(){
			
				var 
					styles = self.gridsStyles(),
					newStyles = [],
					fill = ['1'],
					temp, tmp,
					
					count = self.counter,
					id = 'history' + count;
								
				for(var i=0; i<20; i++){
					temp = self.transcode(styles[i], true).split('');
					tmp = fill.concat(temp);
					tmp.pop();
					newStyles.push(self.transcode(tmp.join('')));
				}
				
				self.span(newStyles.join('-'));
				aider.setFrame(id, newStyles.join('-'));
				
			});
			
			addEvent(update, 'click', function(){
				var
					id = document.getElementById('updateValue').value,
					span = document.getElementById(id),
					count, str;
				
				if(id && span){
					count = id.replace(/[a-z]/g, '');
					str = self.gridsStyles().join('-');
					
					span.frame = str;
					span.innerHTML = self.aElements(count, id, str);
				}
			});
			
			addEvent(run, 'click', function(){
				var 
					history = document.getElementById('history'),
					spans = history.getElementsByTagName('span'),
					frames = [];
					
				for(var i=0; i<spans.length; i++){
				    frames.push(spans[i].frame);
				}
				
				aider.runid = 0;
				aider.frames = frames;
				
				for(var i=0; i<spans.length; i++){
				    
					window.setTimeout(function(){
						self.runDemo();
					}, (i+1)*200);
				}
				
				
			});
		},
		/**
			get current styles of the grids
			[ [010101...]
				...
			  [010101...] ]
		*/
		runDemo : function(){
			var 
				frames = aider.frames,
				i = aider.runid ++;
			
			this.setFrame(false, frames[i]);
		},
		/**
			get current styles of the grids
			[ [010101...]
				...
			  [010101...] ]
		*/
		gridsStyles : function(){
			var 
				grids = this.ref.grids,
				parts = [], k=0, 
				str;
			
			for(var i=0; i<20; i++){
			
				str = '';
		    	while(k<(i+1)*30){
		        	str += aider.state(grids[k++]);
		    	}
		    	parts.push(aider.transcode(str));
			}
			
			return parts;
		},
		/**
			create span element
		*/
		span : function(str){
			var 
				history = document.getElementById('history'),
				count = this.counter++,
				id = 'history' + count,
				el;
				
			el = this.create('span');
			el.id = id;
			el.frame = str;
			
			el.innerHTML = this.aElements(count, id, str);			
			history.appendChild(el);
		},
		/**
			generate a element
		*/
		aElements : function(count, id, str){
			
			return ('<a href="javascript:setFrame(\'' + id + '\', ' + 
				 	'\'' + str + '\')">' + count + '</a>&nbsp;' +
				 	'<a href="javascript:delFrame(\'' + id + '\')">x</a>&nbsp;&nbsp;&nbsp;');
			
		},
		/**
			create element function
		*/
		create : function(elem){
			return document.createElementNS ?
				document.createElementNS('http://www.w3.org/1999/xhtml',elem) :
				document.createElement(elem);
		},
		/**
			set a frame
		*/
		setFrame : function(id, str){
			var 
				updateid = document.getElementById('updateValue'),
				frame = str.split('-'),
				section = [], strip;
			
			if(id)
				updateid.value = id;
			
			for(var i=0; i<frame.length; i++){
				
			    section.push(this.transcode(frame[i], true));

			}
			
			strip = section.join('');
			this.updateScreen(strip);
		},
		/**
			run a frame animation
		*/
		updateScreen : function(strip){
			var 
				states = strip.split('');
				
			for(var i=0; i<states.length; i++){
			    this.updateElState(states[i], i);
			}
			
		},
		/**
			set color to element
			under conditions
		*/
		updateElState : function(state, i){
		
			var 
				grids = this.ref.grids,
				color;
			
			if(state == 1)
				color = 'rgb(128, 128, 128)';
			else
				color = 'rgb(192, 192, 192)';
					
			grids[i].style.backgroundColor = color;
		},
		/**
			delete span element
		*/
		delFrame : function(id){
			var 
				span = document.getElementById(id);
				
			span.parentNode.removeChild(span);
		}
	};
	
	
	
	
muMake.prototype = {
	make : function(prop){
		var 
			cfg = {
				prop: prop
			},
			len = arguments.length,
			p, param;				
				
		for(var i=1; i<len; i++){
			param = arguments[i];
			switch(typeof param) {
				case "number":
					
					break;
				
				case "string":
					
					break;
					
				case "function":
					
					break;
				
				case "object":
					for(p in param) {
						cfg[p] = param[p];
					}			
			}
		}
		
		aider.make(this).monitorClick();
		
		return this;
	},
	
	setFrame : function(id, str){
		aider.setFrame(id, str);
	},
	
	delFrame : function(id){
		aider.delFrame(id);
	}
};





var screen = document.getElementById("screen"),
	grids = screen.getElementsByTagName("div");

var obj = {};
				
obj.grids = grids;

var mu = mooluMake(obj).make();
				
window.setFrame = mu.setFrame;
window.delFrame = mu.delFrame;

})(window);